#include "sys_audio.h"
#include "sys_types.h"
#include "sys_uart.h"
#include "sys_interrupt.h"
#include "sys_delay.h"
#include "sys_gpio.h"
#include "sys_io.h"
#ifdef AUDIO_FILE_MODE_FATFS		
	#include "ff.h"
#endif
#include "sys_timer.h"
#include <string.h>
#include "sys_cache.h"
#include "sys_dma.h"
#include <string.h>
#include <stdio.h>
#ifdef I2S_EN
	#include "sys_i2s.h"
#endif

#ifdef MP3_EN
//mp3
#include "mp3dec.h"
#include "mp3common.h"
#endif

/* 模块定义
#define I2S_EN	
#define MP3_EN
#define WAV_EN
#define RECORED_EN
#define AUDIO_ADC_EN
#define VIDEO_AVI_PLAY_WAV_EN
#define NES_PLAY_WAV_EN
*/


/*DMA-寄存器地址*/
#define DMA_Base_Address (0x01C02000)
/*寄存器地址*/
#define F1C100S_AUDIO_BASE  (0x01C23C00)
#define AUDIO_BASE    F1C100S_AUDIO_BASE
#define codec         F1C100S_AUDIO_BASE 
//
#define CCU_Base_Address     	  		(u32_t)0x01C20000
#define CCU_BUS_CLK_GATING_REG0 		(u32_t)CCU_Base_Address+0x0060
#define CCU_BUS_CLK_GATING_REG1 		(u32_t)CCU_Base_Address+0x0064
#define CCU_BUS_CLK_GATING_REG2 		(u32_t)CCU_Base_Address+0x0068
#define CCU_BUS_SOFT_RST_REG0 			(u32_t)CCU_Base_Address+0x02C0
#define CCU_BUS_SOFT_RST_REG1 			(u32_t)CCU_Base_Address+0x02C4
#define CCU_BUS_SOFT_RST_REG2 			(u32_t)CCU_Base_Address+0x02D0

//AUDIO CLK
#define PLL_AUDIO_CTRL_REG 						(u32_t)CCU_Base_Address+0x0008
#define AUDIO_CODEC_CLK_REG						(u32_t)CCU_Base_Address+0x0140
#define PLL_AUDIO_BIAS_REG						(u32_t)CCU_Base_Address+0x0224
#define PLL_AUDIO_PAT_CTRL_REG  	    (u32_t)CCU_Base_Address+0x0284


#define AC_DAC_DPC		    0x00
#define AC_DAC_FIFOC	    0x04
#define AC_DAC_FIFOS	    0x08
#define AC_ADC_TXDATA	    0x0c
#define AC_ADC_FIFOC	    0x10
#define AC_ADC_FIFOS	    0x14
#define AC_ADC_RXDATA	    0x18
#define DAC_MIXER_CTRL	    0x20
#define ADC_MIXER_CTRL	    0x24
#define ADDA_TUNE    	      0x28
#define BIAS_DA16_CAL_CTRL0	0x2C
#define BIAS_DA16_CAL_CTRL1	0x34

/*--AV定时器-----------*/
#define AVS_TIME_x AVS_TIME_0

/*--定义按键-----------*/
#define nExit GPIO_READ(GPIOE,GPIO_Pin_3)


int play_exit=0;//播放退出标志
int wait_half_buff=0;//等待最后半个缓存
int play_haff=0;//播放一半的数量
int g_volume=0x38;//初始化音量
__align(4) unsigned char wav_buff[70000];
struct wav_ wav;

#define SampleRate48KHZ 	0//000: 48KHz
#define SampleRate24KHZ 	2//010: 24KHz
#define SampleRate12KHZ		4//100: 12KHz
#define SampleRate192KHZ	6//110: 192KHz
#define SampleRate32KHZ		1//001: 32KHz
#define SampleRate16KHZ		3//011: 16KHz
#define SampleRate8KHZ		5//101: 8KHz
#define SampleRate96KHZ		7//111: 96KHz
//
#define SampleRate44_1KHZ			0//000: 48KHz
#define SampleRate22_05KHZ		2//010: 24KHz
#define SampleRate11_025KHZ		4//100: 12KHz

#define snd_soc_update_bits(Base_Add,Offset,bit,Clear,Value)	write32(Base_Add+Offset,read32(Base_Add+Offset) & (~((u64_t)(Clear)<<bit)) | ((u64_t)(Value)<<bit)    ) 
//#define snd_soc_update_bits(Base_Add,Offset,Clear,Value)	write32(Base_Add+Offset,read32(Base_Add+Offset) & (~((u64_t)(Clear))) | ((u64_t)(Value))    ) 

static int clock_init_f=0;//时钟初始化标志
static int play_init_f=0;//播放初始化标志
static int record_init_f=0;//记录初始化标志

int DMA_Inif_f=0;//DMA初始化标志


/*显示播放时间*/
void show_play_time(int total_time,int now_time)
{
static int ftime=0;
	if(now_time!=ftime)
	{
		ftime=now_time;
		sysprintf("%02d:%02d:%02d----%02d:%02d:%02d \r\n",total_time/3600,total_time%3600/60,total_time%3600%60,now_time/3600,now_time%3600/60,now_time%3600%60);	
	}
}
/////////////////////////////////////////////
/*DMA初始化*/
void AUDIO_DMA_Init(void)
{
	if(DMA_Inif_f==0)//初始化一次
	{
		sysprintf("DMA Init...\r\n");
		DMA_Init();
		DMA_Inif_f=1;		
	}
}
/*DMA初始化*/
void AUDIO_DMA_Exit(void)
{
	DMA_Exit();
	DMA_Inif_f=0;	
}
/*音频DMA参数初始化
play_record 1=dac-play 3=iis-play  2=record 
dma_ch ：dma通道0-3
Source ：目标指针
bcnt	：计数 byte
*/
__align(4) DMA play_dma,record_dma;
void SET_AUDIO_DMA_DATA(int play_record,unsigned int *Source,unsigned int bcnt)
{
	if((play_record==1)||(play_record==3))//play
	{
		
		play_dma.Type=NDMA;//类型 
		play_dma.Ch=0;//通道 	
		play_dma.Byte_Counter=bcnt;//Byte计数	
		play_dma.Continuous_Mode_Enable=1;//连续模式
		play_dma.Read_Byte_Counter_Enable=0;//读计数值使能	
		//---------	
		play_dma.Source_Address=(unsigned int)(Source);//源地址	
		play_dma.Source_Address_Type=DMA_ADDRESS_TYEP_LINEER;//源地址类型
		play_dma.Source_DRQ_Type=NDMAS_DRQ_Type_SDRAM_Memory;//源类型
		play_dma.Source_Data_Width=DMA_DATA_WIDTH_16;//源数据宽度
		play_dma.Source_Burst_Length=DMA_BURST_LENGTH_1;//BURST
		//-----------	
		
		
		if(play_record==1)play_dma.Destination_Address=(unsigned int)(AUDIO_BASE+0x0C);//目标地址
#ifdef I2S_EN
			else if(play_record==3)play_dma.Destination_Address=(unsigned int)(I2S_BASE+SUNXI_DA_TXFIFO);//目标地址
#endif	
		play_dma.Destination_Address_Type=DMA_ADDRESS_TYEP_IO;//目标地址类型
		
		if(play_record==1)play_dma.Destination_DRQ_Type=NDMAD_DRQ_Type_Audio_Codec_DAC;//DAC
#ifdef I2S_EN
		else if(play_record==3)play_dma.Destination_DRQ_Type=NDMAD_DRQ_Type_Daudio;//IIS
#endif	
		play_dma.Destination_Data_Width=DMA_DATA_WIDTH_16;//目标数据宽度
		play_dma.Destination_Burst_Length=DMA_BURST_LENGTH_1;//BURST
		DMA_Config(&play_dma);
		DMA_Enable(&play_dma);	

		//-----------	
	}else if(play_record==2)//record
	{
		record_dma.Type=NDMA;//类型 
		record_dma.Ch=1;//通道 	
		record_dma.Byte_Counter=bcnt;//Byte计数	
		record_dma.Continuous_Mode_Enable=1;//连续模式
		record_dma.Read_Byte_Counter_Enable=0;//读计数值使能	
		//---------	
		record_dma.Source_Address=(unsigned int)(AUDIO_BASE+0x18);//源地址	
		record_dma.Source_Address_Type=DMA_ADDRESS_TYEP_IO;//源地址类型
		record_dma.Source_DRQ_Type=NDMAS_DRQ_Type_Audio_Codec;//源类型
		record_dma.Source_Data_Width=DMA_DATA_WIDTH_16;//源数据宽度
		record_dma.Source_Burst_Length=DMA_BURST_LENGTH_1;//BURST
		//-----------	
		record_dma.Destination_Address=(unsigned int)(Source);//目标地址	
		record_dma.Destination_Address_Type=DMA_ADDRESS_TYEP_LINEER;//目标地址类型
		record_dma.Destination_DRQ_Type=NDMAD_DRQ_Type_SDRAM_Memory;//目标类型
		record_dma.Destination_Data_Width=DMA_DATA_WIDTH_16;//目标数据宽度
		record_dma.Destination_Burst_Length=DMA_BURST_LENGTH_1;//BURST	
		DMA_Config(&record_dma);
		DMA_Enable(&record_dma);		
	}	
}


/*音频初始化
play_init   =1 播放初始化
record_init =1 录音初始化
record_init =2 ADC模式初始化
*/
void AUDIO_Init(int play_init,int record_init)
{
	
	if(clock_init_f==0)
	{
	  clock_init_f=1;
		sysprintf("AUDIO CLOCK Init...\r\n");
		//使能总线AUDIO时钟
		write32(CCU_BUS_CLK_GATING_REG2,read32(CCU_BUS_CLK_GATING_REG2)|(1)<<0);
		
		//使能AUDIO复位
		C_BIT(CCU_BUS_SOFT_RST_REG2,0);
		delay_ms(1);	
		S_BIT(CCU_BUS_SOFT_RST_REG2,0);
		delay_ms(1);
		
		//PLL使能
		S_BIT(PLL_AUDIO_CTRL_REG,31);
		//等PLL有效
		while((read32(PLL_AUDIO_CTRL_REG)&(1<<28))==0);
	}
	//播放初始化
	if((play_init==1)&&(play_init_f==0))
	{
		sysprintf("AUDIO PLAY Init...\r\n");
		play_init_f=1;
		#define DAC_DRQ_CLR_CNT			21
		#define FIFO_FLUSH					0
		#define FIR_VER							28
		#define ADC_FIFO_FLUSH			0
		#define PH_COM_FC        		22
		#define PH_COM_PROTEC      	21
		#define HP_VOL              0
		#define EN_DAC							31
		#define HP_POWER_EN					15	
		#define R_MIXER_MUTE_R_DAC	17
		#define R_MIXER_MUTE_L_DAC	16
		#define L_MIXER_MUTE_R_DAC	9
		#define L_MIXER_MUTE_L_DAC	8
		#define PH_R_MUTE						27  
		#define PH_L_MUTE						26  
		#define DAC_AG_R_EN					31  
		#define DAC_AG_L_EN					30  
		
		snd_soc_update_bits(codec, AC_DAC_FIFOC,DAC_DRQ_CLR_CNT,0x3,0x3);
		snd_soc_update_bits(codec, AC_DAC_FIFOC,FIFO_FLUSH,0x1,0x1);
		
		if(0)//MIC-FMINRL-LINEIN 直接输出到播放混频器-直接输出声音
		{
			snd_soc_update_bits(codec, 0X24,24,0x7,0x7);//直接音频输出时要写0
			snd_soc_update_bits(codec, 0X24,3,0x1,0x1); //MIC Boost AMP Enable
			snd_soc_update_bits(codec, 0X24,0,0x7,0x7); //直接音频输出时要写0
			//FMIN-R-L INE直接输入到音频时adc音量控制要写为0
//			snd_soc_update_bits(codec, 0X24,4,0x7,0x0);//FMIN LR增益控制-0最小7最大
//			snd_soc_update_bits(codec, 0X24,21,0x7,0x0);//LINE 增益控制-0最小7最大
			//设置路径为模拟混合器
			snd_soc_update_bits(codec, 0X20,28,0x1,0x1);//使能模拟混合器
			snd_soc_update_bits(codec, 0X20,29,0x1,0x1);
			snd_soc_update_bits(codec, 0X20,24,0x1,0x1);//通过模拟混合器
			snd_soc_update_bits(codec, 0X20,25,0x1,0x1);
			//设置为非静音
			snd_soc_update_bits(codec, DAC_MIXER_CTRL,12,0x1,0x1);//MIC
//			snd_soc_update_bits(codec, DAC_MIXER_CTRL,11,0x1,0x1);//LINE
//			snd_soc_update_bits(codec, DAC_MIXER_CTRL,10,0x1,0x1);//FMIN-L
			snd_soc_update_bits(codec, DAC_MIXER_CTRL,20,0x1,0x1);//MIC	
//			snd_soc_update_bits(codec, DAC_MIXER_CTRL,19,0x1,0x1);//LINE		
//			snd_soc_update_bits(codec, DAC_MIXER_CTRL,18,0x1,0x1);//FMIN-R	
		}
		
		/*
		*	0:64-Tap FIR
		*	1:32-Tap FIR
		*/	
		snd_soc_update_bits(codec, AC_DAC_FIFOC,FIR_VER,0x1,0x0);	
		snd_soc_update_bits(codec, AC_ADC_FIFOC,ADC_FIFO_FLUSH,0x1,0x1);
		
		snd_soc_update_bits(codec, DAC_MIXER_CTRL,PH_COM_PROTEC,0x1,0x1);
		snd_soc_update_bits(codec, DAC_MIXER_CTRL,PH_COM_FC,0x3,0x3);	
		snd_soc_update_bits(codec, DAC_MIXER_CTRL,HP_VOL,0x3f,g_volume);/* set hp volume */
		snd_soc_update_bits(codec, AC_DAC_DPC,EN_DAC,0x1,0x1);
		
		snd_soc_update_bits(codec, DAC_MIXER_CTRL,HP_POWER_EN,0x1,0x1);	/* power hp */
		
		snd_soc_update_bits(codec, DAC_MIXER_CTRL,L_MIXER_MUTE_R_DAC,0x1,0x1);	
		snd_soc_update_bits(codec, DAC_MIXER_CTRL,L_MIXER_MUTE_L_DAC,0x1,0x1);
		
		snd_soc_update_bits(codec, DAC_MIXER_CTRL,R_MIXER_MUTE_R_DAC,0x1,0x1);	
		snd_soc_update_bits(codec, DAC_MIXER_CTRL,R_MIXER_MUTE_L_DAC,0x1,0x1);	

		
		snd_soc_update_bits(codec, DAC_MIXER_CTRL,PH_L_MUTE,0x1,0x1);	
		snd_soc_update_bits(codec, DAC_MIXER_CTRL,PH_R_MUTE,0x1,0x1);	

		snd_soc_update_bits(codec, DAC_MIXER_CTRL,DAC_AG_L_EN,0x1,0x1);	
		snd_soc_update_bits(codec, DAC_MIXER_CTRL,DAC_AG_R_EN,0x1,0x1);	
		/*音频放大开关控制,需要先初始化，再开外部放大器，不然初始化时有杂音*/
			
		//数据中断
		S_BIT(AUDIO_BASE+4,4);
		//时钟选通
		S_BIT(AUDIO_CODEC_CLK_REG,31);//第一次开启HP_POWER与选通时钟都会发出杂音。
		//第一次播放前面播放不完整->加入延时最少150ms
		delay_ms(100);
		//GPIO_RESET(GPIOE,GPIO_Pin_12);//这里打开功放使能脚位，避开杂音
		delay_ms(200);
		//发送最后采样
//		S_BIT(AUDIO_BASE+4,26);
	}
	//录音初始化
	if((record_init==1)&&(record_init_f==0))
	{
		record_init_f=1;
		sysprintf("AUDIO RECORD Init...\r\n");
		//ADC模拟部分使能
		snd_soc_update_bits(codec, 0X24,31,0x1,0x1);
		//ADC数字部分使能		
		snd_soc_update_bits(codec, 0X10,28,0x1,0x1);
		//延时
		
		snd_soc_update_bits(codec, 0X10,0,0x1,0x1);//ADC_FIFO_FLUSH
		snd_soc_update_bits(codec, 0X10,8,0x1f,0x0);//多少样本数触发DMA中断
		//MIC
		//MIC输入硬件无下拉阻容时增益要减小，不然失真  ,有下拉阻容会出现低频震荡音
		
		snd_soc_update_bits(codec, 0X24,24,0x7,0x5);//MIC 增益设置 直接音频输出时要写0 
		snd_soc_update_bits(codec, 0X24,3,0x1,0x1); //MIC Boost AMP Enable
		snd_soc_update_bits(codec, 0X24,0,0x7,0x5); //MIC Boost增益设置 直接音频输出时要写0 
		//FMIN-R-L INE直接输入到音频时adc音量控制要写为0
		snd_soc_update_bits(codec, 0X24,4,0x7,0x4); //FMIN LR音量
		snd_soc_update_bits(codec, 0X24,21,0x7,0x4);//LINE 音量

		snd_soc_update_bits(codec, 0X24,16,0x7,7);//ADC Input Gain Control 
		//数据中断
		S_BIT(AUDIO_BASE+0x10,4);
		//时钟选通
		S_BIT(AUDIO_CODEC_CLK_REG,31);//第一次开启HP_POWER与选通时钟都会发出杂音。
	}
	//通用ADC初始化
	else if((record_init==2)&&(record_init_f==0))
	{
		record_init_f=1;
		sysprintf("AUDIO ADC Init...\r\n");
		//ADC模拟部分使能
		snd_soc_update_bits(codec, 0X24,31,0x1,0x1);
		//ADC数字部分使能		
		snd_soc_update_bits(codec, 0X10,28,0x1,0x1);
		//延时
		
		snd_soc_update_bits(codec, 0X10,0,0x1,0x1);//ADC_FIFO_FLUSH
		snd_soc_update_bits(codec, 0X10,8,0x1f,0x0);//多少样本数触发DMA中断
		snd_soc_update_bits(codec, 0X24,24,0x7,0x0);//MIC增益设置
		snd_soc_update_bits(codec, 0X24,3,0x1,0x0); //MIC Boost AMP Enable
		snd_soc_update_bits(codec, 0X24,0,0x7,0x0); //MIC Boost增益设置
		snd_soc_update_bits(codec, 0X24,4,0x7,0x0); //FMIN LR音量
		snd_soc_update_bits(codec, 0X24,21,0x7,0x0);//LINE 音量

		snd_soc_update_bits(codec, 0X24,16,0x7,0x3);//ADC Input Gain Control
	}
}

/*录音初始化*/
int AUDIO_RECORD_Init(struct wav_ * wav_f)	
{
int s=0,n=0,m=0;	

	switch(wav_f->sample_rate)
	{
		case 48000:
			s=SampleRate48KHZ;n=0x55;m=0x14;
			break;
		case 24000:
			s=SampleRate24KHZ;n=0x55;m=0x14;
			break;	
		case 12000:
			s=SampleRate12KHZ;n=0x55;m=0x14;
			break;
		case 192000:
			s=SampleRate192KHZ;n=0x55;m=0x14;
			break;	
		case 32000:
			s=SampleRate32KHZ;n=0x55;m=0x14;
			break;
		case 16000:
			s=SampleRate16KHZ;n=0x55;m=0x14;
			break;			
		case 8000:
			s=SampleRate8KHZ;n=0x55;m=0x14;
			break;
		case 96000:
			s=SampleRate96KHZ;n=0x55;m=0x14;
			break;	
		case 44100:
			s=SampleRate44_1KHZ;n=0x4E;m=0x14;
			break;			
		case 22050:
			s=SampleRate22_05KHZ;n=0x4E;m=0x14;
			break;
		case 11025:
			s=SampleRate11_025KHZ;n=0x4E;m=0x14;
			break;	
		default:
			return -1;
	}
	//PLL关
	C_BIT(PLL_AUDIO_CTRL_REG,31);
	
	//-设置PLL-N
	C_Vlue(PLL_AUDIO_CTRL_REG,8,0x7f);
	S_Vlue(PLL_AUDIO_CTRL_REG,8,n);
	//-设置PLL-M
	C_Vlue(PLL_AUDIO_CTRL_REG,0,0x1f);
	S_Vlue(PLL_AUDIO_CTRL_REG,0,m);

	//PLL使能
	S_BIT(PLL_AUDIO_CTRL_REG,31);
	//等PLL有效
	while((read32(PLL_AUDIO_CTRL_REG)&(1<<28))==0);
			
		
	/*设置采样周期*/
	C_Vlue(AUDIO_BASE+0x10,29,0x7);
	S_Vlue(AUDIO_BASE+0x10,29,s);
	
	
	/*设置采样位宽*/
	if(wav_f->bits_per_sample==16)
		C_BIT(AUDIO_BASE+0x10,6); //16位
	else if(wav_f->bits_per_sample==24)
		S_BIT(AUDIO_BASE+0x10,6); //24位
	else return -1;
	
	/*设置采样*/
	if(wav_f->bits_per_sample==16)
	{
		/*设置采样低16位*/
		S_BIT(AUDIO_BASE+0x10,24);	
	}
	else if(wav_f->bits_per_sample==24)
	{
		/*设置采样高24位*/
		C_BIT(AUDIO_BASE+0x10,24);
	}
	else return -1;
	
	/*设置为单声道*/
	if(wav_f->num_channels==1)
		S_BIT(AUDIO_BASE+0x10,7);//单声道
	else if(wav_f->num_channels==2)
		C_BIT(AUDIO_BASE+0x10,7);//双声道
	else return -1;
	
	//清采样计数
	write32(AUDIO_BASE+0x44,0);
	
return 0;
}
/*播放初始化*/
int AUDIO_PLAY_Init(struct wav_ * wav_f)	
{
int s=0,n=0,m=0;	

	switch(wav_f->sample_rate)
	{
		case 48000:
			s=SampleRate48KHZ;n=0x55;m=0x14;
			break;
		case 24000:
			s=SampleRate24KHZ;n=0x55;m=0x14;
			break;	
		case 12000:
			s=SampleRate12KHZ;n=0x55;m=0x14;
			break;
		case 192000:
			s=SampleRate192KHZ;n=0x55;m=0x14;
			break;	
		case 32000:
			s=SampleRate32KHZ;n=0x55;m=0x14;
			break;
		case 16000:
			s=SampleRate16KHZ;n=0x55;m=0x14;
			break;			
		case 8000:
			s=SampleRate8KHZ;n=0x55;m=0x14;
			break;
		case 96000:
			s=SampleRate96KHZ;n=0x55;m=0x14;
			break;	
		case 44100:
			s=SampleRate44_1KHZ;n=0x4E;m=0x14;
			break;			
		case 22050:
			s=SampleRate22_05KHZ;n=0x4E;m=0x14;
			break;
		case 11025:
			s=SampleRate11_025KHZ;n=0x4E;m=0x14;
			break;	
		default:
			return -1;
	}
	//PLL关
	C_BIT(PLL_AUDIO_CTRL_REG,31);
	
	//-设置PLL-N
	C_Vlue(PLL_AUDIO_CTRL_REG,8,0x7f);
	S_Vlue(PLL_AUDIO_CTRL_REG,8,n);
	//-设置PLL-M
	C_Vlue(PLL_AUDIO_CTRL_REG,0,0x1f);
	S_Vlue(PLL_AUDIO_CTRL_REG,0,m);

	//PLL使能
	S_BIT(PLL_AUDIO_CTRL_REG,31);
	//等PLL有效
	while((read32(PLL_AUDIO_CTRL_REG)&(1<<28))==0);
			
		
	/*设置采样周期*/
	C_Vlue(AUDIO_BASE+4,29,0x7);
	S_Vlue(AUDIO_BASE+4,29,s);
	
	
	/*设置采样位宽*/
	if(wav_f->bits_per_sample==16)
		C_BIT(AUDIO_BASE+4,5); //16位
	else if(wav_f->bits_per_sample==24)
		S_BIT(AUDIO_BASE+4,5); //24位
	else return -1;
	
	/*设置采样*/
	if(wav_f->bits_per_sample==16)
	{
		/*设置采样低16位*/
		C_Vlue(AUDIO_BASE+4,24,0x3);
		S_Vlue(AUDIO_BASE+4,24,0x3);	
	}
	else if(wav_f->bits_per_sample==24)
	{
		/*设置采样高24位*/
		C_Vlue(AUDIO_BASE+4,24,0x3);
	}
	else return -1;
	
	/*设置为单声道*/
	if(wav_f->num_channels==1)
		S_BIT(AUDIO_BASE+4,6);//单声道
	else if(wav_f->num_channels==2)
		C_BIT(AUDIO_BASE+4,6);//双声道
	else return -1;
	
	//清采样计数
	write32(AUDIO_BASE+0x40,0);
	
return 0;
}
/*播放WAV MP3文件*/
void MP3WAVplay(char *path)
{
	char *Fn=path+(strlen(path)-4);
	
	sysprintf("---------------------------------------------\r\n",path);
	sysprintf("播放路径 %s \r\n",path);
	sysprintf("---------------------------------------------\r\n",path);

	if( (strcmp(Fn,".mp3")==0) || (strcmp(Fn,".MP3")==0) )
	{
#ifdef 	MP3_EN
		_MP3_Play(0,path,0,0,0);
#else
		sysprintf("ERR:MP3_EN is not defined\r\n");	
#endif		
	}
	else if( (strcmp(Fn,".wav")==0) || (strcmp(Fn,".WAV")==0) )
	{
#ifdef 	WAV_EN	
		_WAV_Play(0,path,0,0,0);
#else
		sysprintf("ERR:WAV_EN is not defined\r\n");	
#endif		
	}else
	{
		sysprintf("不是mp3/wav文件\r\n");
	}
}
/*退出播放*/
void MP3WAVplay_exit(void)
{
	play_exit=1;
}

#ifdef 	WAV_EN
/*
file_mode 文件模式 FILE_MODE_FATFS=文件系统 FILE_MODE_BUFF=内置
path file_mode=FILE_MODE_FATFS时为文件路径
File file_mode=FILE_MODE_BUFF时为文件缓存指针
File_size file_mode=FILE_MODE_BUFF时为文件缓存大小
out_mode 音频输出模式 OUT_MODE_DAC=内置DAC OUT_MODE_IIS=IIS
*/
int _WAV_Play(int file_mode,char *path,char *File,int File_size,int out_mode)
{
#define ReadSize (44100*2*2/30)/*一次读取数据大小*/
int nexts=0;		
int i;
char buff[8192];
int res=0;
	
#ifdef AUDIO_FILE_MODE_FATFS		
	aFIL fp1;	
#endif
	
int wav_play_time=0;//播放时长

	  sysprintf("----------WAV PLAY----------\r\n");
	  if(file_mode==FILE_MODE_FATFS)
		{
			
#ifdef AUDIO_FILE_MODE_FATFS	
			if(path==NULL)
			{
				sysprintf("No path input..\r\n");		
				return -4;
			}
			res=f_open(&fp1,path,FA_OPEN_EXISTING|FA_READ);
			if(res==5)
			{
				sysprintf("The folder path does not exist..\r\n");	
				return -3;
			}
			if(res==4)
			{
				sysprintf("The WAV file was not found..\r\n");
				return -2;
			}
#else
				return -1;
#endif			
		}
		else
		{
			if(File==NULL)
			{
				sysprintf("No WAV buffer file input..\r\n");
				return -4;
			}
			res=0;
		}
		if(res==0)
		{
			sysprintf("WAV file opened successfully..\r\n");

			/*解WAV文件*/
			if(file_mode==FILE_MODE_FATFS)
			{
#ifdef AUDIO_FILE_MODE_FATFS	
				f_read(&fp1,buff,58,NULL);
#endif
			}
			else
				memcpy(buff,&File[0],58);
			
			wav.audio_format=buff[21]<<8|buff[20];
			wav.num_channels=buff[23]<<8|buff[22];		
			wav.bits_per_sample=buff[35]<<8|buff[34];
			wav.byte_rate=buff[31]<<24|buff[30]<<16|buff[29]<<8|buff[28];
			wav.sample_rate=buff[27]<<24|buff[26]<<16|buff[25]<<8|buff[24];	
			wav.format_blok_lenght=buff[19]<<24|buff[18]<<16|buff[17]<<8|buff[16];	
	    //data-LIST 判断
	    i=16+wav.format_blok_lenght+4;
	    if((buff[i+0]=='d')&&(buff[i+1]=='a')&&(buff[i+2]=='t')&&(buff[i+3]=='a'))
	    {
				sysprintf("data\r\n");
				i=16+wav.format_blok_lenght+4+4;
				//-------------------------------------------------------------
				wav.data_size=buff[i+3]<<24|buff[i+2]<<16|buff[i+1]<<8|buff[i+0];
				wav.play_time_ms=(int)((float)wav.data_size*(float)1000/(float)wav.byte_rate);				
			}else if((buff[i+0]=='L')&&(buff[i+1]=='I')&&(buff[i+2]=='S')&&(buff[i+3]=='T'))
			{
				sysprintf("LIST\r\n");				
			  i=16+wav.format_blok_lenght+4+4+(buff[i+3+4]<<24|buff[i+2+4]<<16|buff[i+1+4]<<8|buff[i+0+4])+8;
			if(file_mode==FILE_MODE_FATFS)
			{
#ifdef AUDIO_FILE_MODE_FATFS					
				f_lseek(&fp1,i);
				f_read(&fp1,buff,4,NULL);
#endif				
			}
			else
				memcpy(buff,&File[i],4);	
			
				i=0;
				//-------------------------------------------------------------
				wav.data_size=buff[i+3]<<24|buff[i+2]<<16|buff[i+1]<<8|buff[i+0];
				wav.play_time_ms=(int)((float)wav.data_size*(float)1000/(float)wav.byte_rate);	
			}

			
			/*输出*/
     	sysprintf("audio_format:%d \r\n",wav.audio_format);
      sysprintf("num_channels:%d \r\n",wav.num_channels);
     	sysprintf("bits_per_sample:%d bit\r\n",wav.bits_per_sample);
      sysprintf("sample_rate:%d Hz\r\n",wav.sample_rate);
      sysprintf("byte_rate:%d Byte/S\r\n",wav.byte_rate);
			sysprintf("format_blok_lenght):%d Byte\r\n",wav.format_blok_lenght);
			sysprintf("data_size:%d Byte\r\n",wav.data_size);
			wav_play_time=wav.play_time_ms/1000;
			sysprintf("play time:%02d:%02d:%02d \r\n",wav_play_time/3600,wav_play_time%3600/60,wav_play_time%3600%60);
						
			/*无压缩格式*/
			if(wav.audio_format==1)
			{	
				/*音频初始化*/
				AUDIO_DMA_Init();		
				if(out_mode==OUT_MODE_DAC)
				{
					AUDIO_Init(1,0);
				}else
				{
#ifdef I2S_EN
					i2s_init();
#else
					sysprintf("ERR:I2S_EN is not defined\r\n");			
#endif				
				}				
				AVS_Time_Init(AVS_TIME_x,100);	
				wait_half_buff=0;//等待最后半个缓存
				play_haff=0;//播放一半的数量		
				

				/*读出数据区*/
				unsigned int br=0;

				if(file_mode==FILE_MODE_FATFS)
				{
#ifdef AUDIO_FILE_MODE_FATFS						
					f_lseek(&fp1,i+4);	
					f_read(&fp1,&wav_buff[0],ReadSize*2,&br);
#endif	
				}
				else
				{
					memcpy(&wav_buff[0],&File[i+4],ReadSize*2);	
					i=i+4+ReadSize*2;
				}
        sysFlushCache(D_CACHE);
				
				//初始化参数 
				if(out_mode==OUT_MODE_DAC)
				{
					res=AUDIO_PLAY_Init(&wav);
				}else
				{
#ifdef I2S_EN			
					res=i2s_config(wav.num_channels,wav.sample_rate);
#endif		
				}
				if(res==0)
				{
					sysprintf("play...\r\n");						
					//dma初始化
					SET_AUDIO_DMA_DATA(out_mode==OUT_MODE_DAC?1:3,(unsigned int *)(&wav_buff[0]),ReadSize*2);
					//开始计时器
					AVS_Time_Start(AVS_TIME_0);
					//循环播放
					while(1)
					{
						//全传输完标志
						if(DMA_Get_Full_TIP(&play_dma))//全传输
						{
							if(wait_half_buff==0)
							{
								if(file_mode==FILE_MODE_FATFS)
								{
#ifdef AUDIO_FILE_MODE_FATFS			
									f_read(&fp1,&wav_buff[ReadSize],ReadSize,&br);
#endif									
								}
								else
								{
									if((i+ReadSize)>=File_size)//文件超出
									{
										memcpy(&wav_buff[ReadSize],&File[i],File_size-i); 
										br=File_size-i;
										i=i+br;	
									}
									else//正常复制
									{
										memcpy(&wav_buff[ReadSize],&File[i],ReadSize);	
										i=i+ReadSize;
										br=ReadSize;
									}
								}
								if(br>0)
								{
									if(br!=ReadSize)//缓存尾清0
									{
										memset(&wav_buff[ReadSize+br],0,ReadSize-br);
									}	
								}else//清空缓存
								{
									memset(&wav_buff[ReadSize],0,ReadSize);
								}
								sysFlushCache(D_CACHE);
							}
							else 
							{
								wait_half_buff=2;/*播放结束-下一步关DMA*/	
							}						
						}	
						//半传输完标志		
						if(DMA_Get_Half_TIP(&play_dma))//半传输
						{
							if(file_mode==FILE_MODE_FATFS)
							{
#ifdef AUDIO_FILE_MODE_FATFS									
								f_read(&fp1,&wav_buff[0],ReadSize,&br);
#endif						
							}
							else
							{
								if((i+ReadSize)>=File_size)//文件超出
								{
									memcpy(&wav_buff[0],&File[i],File_size-i); 
									br=File_size-i;
									i=i+br;
								}
								else//正常复制
								{
									memcpy(&wav_buff[0],&File[i],ReadSize);	
									i=i+ReadSize;
									br=ReadSize;
								}
							}
							if(br>0)
							{
								if(br!=ReadSize)//缓存尾清0
								{
									memset(&wav_buff[0+br],0,ReadSize-br);
								}
								sysFlushCache(D_CACHE);
							}
							else 
							{
								wait_half_buff=1;//播放结束-现在等剩下半个缓存播放结束
							}				
						}
						//播放完成退出
						if(wait_half_buff==2)
						{	
							DMA_Disable(&play_dma);
							AVS_Time_Stop(AVS_TIME_0);					
							sysprintf("wav play end...\r\n");						 
							break;
						}
						//显示播放时间
						show_play_time(wav_play_time,AVS_Time_Read(AVS_TIME_0)/10/1000);						
						//退出播放				
						if((nExit==0)&&(nexts==0))nexts=1;
						if((nExit==1)&&(nexts==1))play_exit=1;//等弹起		
						/*播放退出*/
						if(play_exit==1)
						{
							DMA_Disable(&play_dma);				
							AVS_Time_Stop(AVS_TIME_0);
							play_exit=0;
							sysprintf("wav play exit...\r\n");						
							break;
						}	
					} 
				}else sysprintf("ERR:parameter error\r\n");
			}else  sysprintf("ERR:format error\r\n");
#ifdef AUDIO_FILE_MODE_FATFS				
			if(file_mode==FILE_MODE_FATFS)f_close(&fp1);			
#endif			
			sysprintf("file close.\r\n");			
			sysprintf("\r\n\r\n\r\n");			
		}
		return 0;
}
#endif

#ifdef MP3_EN
/*mp3解码测试*/
int Get_ID3V2(int file_mode,char *File,int File_size,aFIL f,char *TIT2,char *TPE1,char *TALB);
int Get_ID3V1(int file_mode,char *File,int File_size,aFIL f,char *TIT2,char *TPE1,char *TALB);
int Get_mp3_play_time_ms(int file_mode,char *File,int File_size,int ID3size,int ID3V1_size,aFIL f,MP3FrameInfo _mp3FrameInfo);
int MP3_to_PCM_DATA(int file_mode,char *File,int File_size,HMP3Decoder Mp3Decoder,MP3FrameInfo *mp3FrameInfo,aFIL f,unsigned char *outbuff,int data_init,int read_addr);
/*
file_mode 文件模式 FILE_MODE_FATFS=文件系统 FILE_MODE_BUFF=内置
path file_mode=FILE_MODE_FATFS时为文件路径
File file_mode=FILE_MODE_BUFF时为文件缓存指针
File_size file_mode=FILE_MODE_BUFF时为文件缓存大小
out_mode 音频输出模式 OUT_MODE_DAC=内置DAC OUT_MODE_IIS=IIS
*/
int _MP3_Play(int file_mode,char *path,char *File,int File_size,int out_mode)
{
	int nexts=0;		
	int Frame_size;
	int mp3_play_time=0;//播放时长
	int offset=0;
	unsigned char *readPtr=0;//输入数据缓冲
	int Padding=0;//Padding位
	int bytesLeft=0;
	MP3FrameInfo mp3FrameInfo;
	HMP3Decoder Mp3Decoder=0;
		//TIT2：歌曲标题名字
		//TPE1：作者名字
		//TALB：作品专辑	
	char TIT2[100];
	char TPE1[100];
	char TALB[100];
	int ID3v1=0,ID3v2=0;//ID3大小
	//
	int res;
	aFIL f;	

	sysprintf("----------MP3 PLAY----------\r\n");
  if(file_mode==FILE_MODE_FATFS)	
	{
#ifdef AUDIO_FILE_MODE_FATFS			
		if(path==NULL)
		{
			sysprintf("No path input..\r\n");	
			return -4;
		}
		res=f_open(&f,path,FA_OPEN_EXISTING|FA_READ);
		if(res==5)
		{
			sysprintf("The folder path does not exist..\r\n");	
			return -3;
		}		
		if(res==4)
		{
			sysprintf("The MP3 file was not found..\r\n");	
			return -3;
		}
		if(res==0)sysprintf("MP3 file opened successfully..\r\n");
#else		
		return -1;
#endif
	}else
	{
		if(File==NULL)
		{
			sysprintf("No MP3 buffer file input..\r\n");	
			return -4;
		}
	}	
	//
	readPtr=wav_buff;
	/*读入一段mp3文件*/

	if(file_mode==FILE_MODE_FATFS)
	{
#ifdef AUDIO_FILE_MODE_FATFS			
		f_read(&f,readPtr,10000,NULL);	
#endif		
	}

	else memcpy(readPtr,&File[0],10000);
	bytesLeft=10000;
	//读ID3
	ID3v1=Get_ID3V1(file_mode,File,File_size,f,TIT2,TPE1,TALB);
	ID3v2=Get_ID3V2(file_mode,File,File_size,f,TIT2,TPE1,TALB);	

	//超出，从新读入数据
  if(ID3v2>10000)
	{
		sysprintf("ID3v2 overlength\r\n");
		readPtr=wav_buff;
		if(file_mode==FILE_MODE_FATFS)
		{
#ifdef AUDIO_FILE_MODE_FATFS			
			f_lseek(&f,ID3v2);
			f_read(&f,readPtr,10000,NULL);
#endif
		}else
		{
			memcpy(readPtr,&File[ID3v2],10000);
		}
		bytesLeft=10000;
	}else
	{
		if(ID3v2>0)offset+=ID3v2;//如果有ID3V2偏移到下一个帧
		readPtr+=offset;
		bytesLeft-=offset;
	}
	
RE_MP3GetNextFrameInfo:
	/*【参数1：输入数据的缓存指针】【 参数2: 输入数据帧的剩余大小】*/
	offset= MP3FindSyncWord(readPtr,bytesLeft);//找帧头
	
	unsigned char *readPtr_x=readPtr;
	int bytesLeft_x=bytesLeft;
	readPtr+=offset;
	bytesLeft-=offset;
	
	if(offset<0)
	{
#ifdef AUDIO_FILE_MODE_FATFS			
			if(file_mode==FILE_MODE_FATFS)f_close(&f);	
#endif	
		return -1;
	}
	else
	{
		if(Mp3Decoder==0)
		{
			Mp3Decoder=MP3InitDecoder(); 
		}
		if(Mp3Decoder==0)
		{
			sysprintf("Init Mp3Decoder failed!\r\n");
#ifdef AUDIO_FILE_MODE_FATFS			
			if(file_mode==FILE_MODE_FATFS)f_close(&f);	
#endif		
			return -1;
		}	

		/*返回帧头信息*/
    if(ERR_MP3_NONE==MP3GetNextFrameInfo(Mp3Decoder,&mp3FrameInfo,readPtr))	
		{			
			/*打印帧头信息*/
			sysprintf("FrameInfo bitrate=%d \r\n",mp3FrameInfo.bitrate);
			sysprintf("FrameInfo nChans=%d \r\n",mp3FrameInfo.nChans);
			sysprintf("FrameInfo samprate=%d \r\n",mp3FrameInfo.samprate);
			sysprintf("FrameInfo bitsPerSample=%d \r\n",mp3FrameInfo.bitsPerSample);
			sysprintf("FrameInfo outputSamps=%d \r\n",mp3FrameInfo.outputSamps);	
			sysprintf("FrameInfo layer=%d \r\n",mp3FrameInfo.layer);
			sysprintf("FrameInfo version=%d \r\n",mp3FrameInfo.version);
			/*计算数据帧大小 帧大小 = ( 每帧采样次数 × 比特率(bit/s) ÷ 8 ÷采样率) + Padding*/	
			Frame_size=(int)samplesPerFrameTab[mp3FrameInfo.version][mp3FrameInfo.layer - 1] * mp3FrameInfo.bitrate / 8 / mp3FrameInfo.samprate + Padding;
			sysprintf("FrameInfo Frame_size=%d \r\n",Frame_size);
			//返回播放时长信息
			int t=Get_mp3_play_time_ms(file_mode,File,File_size,ID3v2,ID3v1,f,mp3FrameInfo);
			mp3_play_time=t/1000;
			sysprintf("play time=%02d:%02d:%02d \r\n",mp3_play_time/3600,mp3_play_time%3600/60,mp3_play_time%3600%60);		
		}else
		{
			sysprintf("Unfound FrameInfo.\r\n");
			if(get_fw()==0)//变换帧标志,重新获取帧头信息;
			{
				set_fw(1);
				readPtr=readPtr_x;
				bytesLeft=bytesLeft_x;
				goto RE_MP3GetNextFrameInfo;
			}		
			sysprintf("ERR: MP3GetNextFrameInfo.\r\n");
#ifdef AUDIO_FILE_MODE_FATFS		
			if(file_mode==FILE_MODE_FATFS)f_close(&f);	
#endif
			return -1;
		}		
	}
	/*只能播放MP3文件*/
	if((mp3FrameInfo.layer<3) || (mp3FrameInfo.bitrate<=0) || (mp3FrameInfo.samprate<=0))
	{
		sysprintf("ERR:It's not in mp3 format.\r\n");	
		MP3FreeDecoder(Mp3Decoder);
#ifdef AUDIO_FILE_MODE_FATFS			
			if(file_mode==FILE_MODE_FATFS)f_close(&f);	
#endif		
		return -1;
	}
  wait_half_buff=0;//等待最后半个缓存
	play_haff=0;//播放一半的数量
	/*音频初始化*/
	AUDIO_DMA_Init();	
	if(out_mode==OUT_MODE_DAC)
	{		
		AUDIO_Init(1,0);			
	}else
	{
#ifdef I2S_EN
		i2s_init();
#else
		sysprintf("ERR:I2S_EN is not defined\r\n");	
#endif
	}	

	AVS_Time_Init(AVS_TIME_x,100);	
	/*初始化参数*/
	wav.audio_format=1;
	wav.num_channels=mp3FrameInfo.nChans;	
  wav.bits_per_sample=mp3FrameInfo.bitsPerSample;
	wav.sample_rate=mp3FrameInfo.samprate;	
  /*写入参数*/
	if(wav.audio_format==1)
	{
		//初始化参数 
		if(out_mode==OUT_MODE_DAC)
		{
			res=AUDIO_PLAY_Init(&wav);
		}else
		{
#ifdef I2S_EN	
			res=i2s_config(wav.num_channels,wav.sample_rate);
#endif
		}
		

		if(res==0)
		{
			//dma初始化-需要先解码两个缓存-播放一个，一个备用
			int pcm_data_size;
			memset(wav_buff,0,sizeof wav_buff);		
			pcm_data_size=MP3_to_PCM_DATA(file_mode,File,File_size,Mp3Decoder,&mp3FrameInfo,f,&wav_buff[0],1,ID3v2);	
			pcm_data_size=MP3_to_PCM_DATA(file_mode,File,File_size,Mp3Decoder,&mp3FrameInfo,f,&wav_buff[pcm_data_size],0,0);
	
      sysFlushCache(D_CACHE);			
			if(pcm_data_size<=0)
			{
				MP3FreeDecoder(Mp3Decoder);
#ifdef AUDIO_FILE_MODE_FATFS			
			if(file_mode==FILE_MODE_FATFS)f_close(&f);	
#endif					
				return -2;
			}		
			
			play_haff=pcm_data_size;
			sysprintf("play...\r\n");						
			SET_AUDIO_DMA_DATA(out_mode==OUT_MODE_DAC?1:3,(unsigned int *)(&wav_buff[0]),pcm_data_size*2);
			//开始计时器
			AVS_Time_Start(AVS_TIME_0);
			//检测发送完成中断-中断DMA指向下一缓存，读SD后解码一个缓存
			while(1)
			{
				//全传输完标志
				if(DMA_Get_Full_TIP(&play_dma))//全传输
				{
					if(wait_half_buff==0)
					{
						pcm_data_size=MP3_to_PCM_DATA(file_mode,File,File_size,Mp3Decoder,&mp3FrameInfo,f,&wav_buff[pcm_data_size],0,0);
						if(pcm_data_size>0)
							sysFlushCache(D_CACHE);		
						else 
							wait_half_buff=1;
					}else 
					{
						/*最后半个缓存dma空*/	
						wait_half_buff=2;
					}						
				}	
				//半传输完标志		
				if(DMA_Get_Half_TIP(&play_dma))//半传输
				{
					if(wait_half_buff==0)
					{
						pcm_data_size=MP3_to_PCM_DATA(file_mode,File,File_size,Mp3Decoder,&mp3FrameInfo,f,&wav_buff[0],0,0);
						if(pcm_data_size>0)
							sysFlushCache(D_CACHE);		
						else 
							wait_half_buff=1;						
					}else 
					{
						/*最后半个缓存dma空*/	
						wait_half_buff=2;
					}							
				}
				//播放完成退出
				if(wait_half_buff==2)
				{	
					DMA_Disable(&play_dma);	
					AVS_Time_Stop(AVS_TIME_0);					
					sysprintf("mp3 play end...\r\n");						 
					break;
				}
				//显示播放时间
				show_play_time(mp3_play_time,AVS_Time_Read(AVS_TIME_0)/10/1000);				
				//退出播放				
				if((nExit==0)&&(nexts==0))nexts=1;
				if((nExit==1)&&(nexts==1))play_exit=1;//等弹起		
				/*播放退出*/
				if(play_exit==1)
				{
					DMA_Disable(&play_dma);			
					AVS_Time_Stop(AVS_TIME_0);
					play_exit=0;
					sysprintf("mp3 play exit...\r\n");						
					break;
				}				
			}
		}else sysprintf("ERR:parameter error\r\n");
	}else  sysprintf("ERR:format error\r\n");
	MP3FreeDecoder(Mp3Decoder);
#ifdef AUDIO_FILE_MODE_FATFS		
	if(file_mode==FILE_MODE_FATFS)f_close(&f);	
#endif
	sysprintf("file close.\r\n");		
	sysprintf("\r\n\r\n\r\n");	
	return 0;
}

/*
解码1帧
返回数据大小
Mp3Decoder 初始化指针
mp3FrameInfo 解码信息指针
f FATFS文件指针
outbuff 输出数据指针
data_init 初始化参数
read_addr 第一帧地址 配合data_init用
返回-3 找帧头错误
返回-2 解码错误过多
返回-1 播放完成
*/
#define DATSIZE (1024*2)
__align(4) unsigned char rbuff[DATSIZE];	
int MP3_to_PCM_DATA(int file_mode,char *File,int File_size,HMP3Decoder Mp3Decoder,MP3FrameInfo *mp3FrameInfo,aFIL f,unsigned char *outbuff,int data_init,int read_addr)
{
int offset;
static int res=0;
static int 	ssddtt=0;
static int _bytesLeft=0;//有效长度
static unsigned char *readPtr;//读出指针
unsigned int br;
int outsize;
static int data_read_end=0;
	/*初始化参数*/
	if(data_init==1)
	{
		res=0;
		_bytesLeft=0;
		ssddtt=read_addr;
		readPtr=NULL;
		data_read_end=0;
	}
	/*判断是否需要读入数据*/
	if((_bytesLeft<(MAINBUF_SIZE*2))&&(data_read_end==0))
	{
		/*没有解码的数据复制到开始*/
		memcpy(&rbuff[0],&rbuff[DATSIZE-_bytesLeft],_bytesLeft); 
		/*读入数据*/
		if(file_mode==FILE_MODE_FATFS)
		{
#ifdef AUDIO_FILE_MODE_FATFS			
			f_lseek(&f,ssddtt);
			f_read(&f,rbuff+_bytesLeft,DATSIZE-_bytesLeft,&br);
#endif
		}else
		{
			if((ssddtt+(DATSIZE-_bytesLeft))>=File_size)//文件超出
			{
				memcpy(rbuff+_bytesLeft,&File[ssddtt],File_size-ssddtt); 
				br=File_size-ssddtt;
			}
			else//文件没有超出
			{
				memcpy(rbuff+_bytesLeft,&File[ssddtt],DATSIZE-_bytesLeft);
				br=DATSIZE-_bytesLeft;
			}
		}
		/*数据读完-播放完成*/
		if(br!=(DATSIZE-_bytesLeft))
		{	
			data_read_end=1;
			_bytesLeft=_bytesLeft+br;//有效字节数
			readPtr=rbuff;//数据指针偏移到0					
		}
		else
		{
			ssddtt+=(DATSIZE-_bytesLeft);//偏移到下一下地址
			_bytesLeft=DATSIZE;//有效字节数
			readPtr=rbuff;//数据指针偏移到0	
		}
	}
	/*找帧头*/
	offset= MP3FindSyncWord(readPtr,_bytesLeft);	
	if(offset>=0)
	{
		readPtr+=offset;
		_bytesLeft-=offset;
		/*解码帧-【数据指针+帧长度】与【有效长度-帧长度】*/
		res=MP3Decode(Mp3Decoder,&readPtr,&_bytesLeft,(short *)outbuff, 0);
		if(res<0)
		{
			if(res==ERR_MP3_INVALID_HUFFCODES)//忽略的错误
			{	
				sysprintf("Warning: ERR_MP3_INVALID_HUFFCODES\r\n");
				goto EOUT;
			}	
		return -2;
		}
	}
	else
	{	
		sysprintf("Unfound header.\r\n");	
		return -3;//没有帧头
	}
EOUT:	
	/*返回解码大小*/
	outsize=(mp3FrameInfo->outputSamps*2);		
	return outsize;
}

/*识别ID3V2+
f 文件句柄
//TIT2：歌曲标题名字
//TPE1：作者名字
//TALB：作品专辑
//编码UNICODE
返回数据大小
//https://blog.csdn.net/qq_18661257/article/details/54908775
*/
int Get_ID3V2(int file_mode,char *File,int File_size,aFIL f,char *TIT2,char *TPE1,char *TALB)
{
int s=0,i,l;
int ID3_VER;	
int ID3_SIZE;	
char readbuff[5000];	
int TIT2_size=0;
int TPE1_size=0;
int TALB_size=0;	
int TIT2_F=0;
int TPE1_F=0;
int TALB_F=0;
	/*读入一段mp3文件*/
	if(file_mode==FILE_MODE_FATFS)
	{
#ifdef AUDIO_FILE_MODE_FATFS		
		f_lseek(&f,0);
		f_read(&f,readbuff,5000,NULL);
#endif
	}else
	{
		memcpy(readbuff,&File[0],5000);
	}
	/*ID3_V2识别*/
	for(i=0;i<50;i++)
	{
		if((readbuff[i+0]=='I')&&(readbuff[i+1]=='D')&&(readbuff[i+2]=='3'))
		{ 
			ID3_VER=readbuff[i+3]*10+readbuff[i+4];
			ID3_SIZE = ((readbuff[i+9] & 0x7f) | ((readbuff[i+8] & 0x7f) << 7) | ((readbuff[i+7] & 0x7f) << 14) | ((readbuff[i+6] & 0x7f) << 21)) + 10;
		  sysprintf("ID3V%d.%d \r\n",ID3_VER/10,ID3_VER%10);
			sysprintf("label=%d\r\n",ID3_SIZE);	
			s=ID3_SIZE;
			if(ID3_SIZE>5000)ID3_SIZE=5000;//超长ID3 可能有图片类
			for(;i<ID3_SIZE;i++)
			{
				if(TIT2_F==0)
				if((readbuff[i+0]=='T')&&(readbuff[i+1]=='I')&&(readbuff[i+2]=='T')&&(readbuff[i+3]=='2'))//TIT2
				{
					sysprintf("TIT2=%d \r\n",i);
					TIT2_size=readbuff[i+4+0]<<24 | readbuff[i+4+1]<<16 | readbuff[i+4+2]<<8 | readbuff[i+4+3]<<0;
//					sysprintf("TIT2_size=%d \r\n",TIT2_size);
					for(l=0;l<(TIT2_size-3);l++)TIT2[l]=readbuff[i+10+3+l];
//					for(l=0;l<(TIT2_size-3);l++)sysprintf("0x%02x,",TIT2[l]);
//					sysprintf("\r\n");
					TIT2_F=1;
				}
				if(TPE1_F==0)
				if((readbuff[i+0]=='T')&&(readbuff[i+1]=='P')&&(readbuff[i+2]=='E')&&(readbuff[i+3]=='1'))//TPE1
				{
					sysprintf("TPE1=%d \r\n",i);
					TPE1_size=readbuff[i+4+0]<<24 | readbuff[i+4+1]<<16 | readbuff[i+4+2]<<8 | readbuff[i+4+3]<<0;
//					sysprintf("TPE1_size=%d \r\n",TPE1_size);
					for(l=0;l<(TPE1_size-3);l++)TPE1[l]=readbuff[i+10+3+l];
//					for(l=0;l<(TPE1_size-3);l++)sysprintf("0x%02x,",TPE1[l]);
//					sysprintf("\r\n");
					TPE1_F=1;
				}
				if(TALB_F==0)
				if((readbuff[i+0]=='T')&&(readbuff[i+1]=='A')&&(readbuff[i+2]=='L')&&(readbuff[i+3]=='B'))//TALB
				{
					sysprintf("TALB=%d \r\n",i);
					TALB_size=readbuff[i+4+0]<<24 | readbuff[i+4+1]<<16 | readbuff[i+4+2]<<8 | readbuff[i+4+3]<<0;
//					sysprintf("TALB_size=%d \r\n",TALB_size);
					for(l=0;l<(TALB_size-3);l++)TALB[l]=readbuff[i+10+3+l];
//					for(l=0;l<(TALB_size-3);l++)sysprintf("0x%02x,",TALB[l]);
//					sysprintf("\r\n");
					TALB_F=1;
				}
			}		
		}	
	}
	return s;
}

/*识别ID3V1
f 文件句柄
返回数据大小
//编码GBK2312
*/
int Get_ID3V1(int file_mode,char *File,int File_size,aFIL f,char *TIT2,char *TPE1,char *TALB)
{
	int l;
	/*读最后128字节*/
	char buffl[128];
  if(file_mode==FILE_MODE_FATFS)	
	{
#ifdef AUDIO_FILE_MODE_FATFS			
		int Fsize=f_size(&f);
		f_lseek(&f,Fsize-128);
		f_read(&f,buffl,128,NULL);
#endif
	}else
	{
		memcpy(buffl,&File[File_size-128],128);
	}
	if((buffl[0]=='T')&&(buffl[1]=='A')&&(buffl[2]=='G'))
	{
		sysprintf("ID3V1\r\n");
		for(l=0;l<30;l++)TIT2[l]=buffl[3+l];
		for(l=0;l<30;l++)TPE1[l]=buffl[33+l];
		for(l=0;l<30;l++)TALB[l]=buffl[63+l];
		//编码GBK2312
//		for(l=0;l<10;l++)sysprintf("0x%02x,",TIT2[l]);
//		sysprintf("\r\n");	
		return 128;
	}
	return 0;
}


/*返回播放时长-ms
ID3size ID3大小
ID3V1_size ID3V1 大小
f 文件句柄
_mp3FrameInfo mp3信息指针
*/
int Get_mp3_play_time_ms(int file_mode,char *File,int File_size,int ID3size,int ID3V1_size,aFIL f,MP3FrameInfo _mp3FrameInfo)
{
int time,i;
int VBR_Frame_num;//总帧数
int Fsize;//文件大小	
char readbuff[5000];	
	
	/*读入一段mp3文件*/
	if(file_mode==FILE_MODE_FATFS)
	{
#ifdef AUDIO_FILE_MODE_FATFS				
		f_lseek(&f,ID3size);
		f_read(&f,readbuff,5000,NULL);
		Fsize=f_size(&f); 
#endif	
	}else
	{
		memcpy(readbuff,&File[ID3size],5000);
		Fsize=File_size; 
	}
	//VBR 可变码率
	for(i=0;i<60;i++)
	{

		if(((readbuff[i+0]=='X')&&(readbuff[i+1]=='i')&&(readbuff[i+2]=='n')&&(readbuff[i+3]=='g'))||
			((readbuff[i+0]=='I')&&(readbuff[i+1]=='n')&&(readbuff[i+2]=='f')&&(readbuff[i+3]=='o')))
		{
			
			/*读总帧数*/
			VBR_Frame_num=readbuff[i+8+0]<<24 | readbuff[i+8+1]<<16 | readbuff[i+8+2]<<8 | readbuff[i+8+3]<<0;
			sysprintf("Xing=%d \r\n",i);
			/*计算播放时长*/
			time=(float)VBR_Frame_num*((float)1000000/(float)_mp3FrameInfo.samprate*(float)samplesPerFrameTab[_mp3FrameInfo.version][_mp3FrameInfo.layer - 1])/(float)1000;
			return time;
		}
		if((readbuff[i+0]=='V')&&(readbuff[i+1]=='B')&&(readbuff[i+2]=='R')&&(readbuff[i+3]=='I'))
		{
			sysprintf("VBRI=%d \r\n",i);
			/*读总帧数*/
			VBR_Frame_num=readbuff[i+14+0]<<24 | readbuff[i+14+1]<<16 | readbuff[i+14+2]<<8 | readbuff[i+14+3]<<0;
			/*计算播放时长*/
			time=(float)VBR_Frame_num*((float)1000000/(float)_mp3FrameInfo.samprate*(float)samplesPerFrameTab[_mp3FrameInfo.version][_mp3FrameInfo.layer - 1])/(float)1000;
			return time;
		}
	}
	//CBR 固定码率

	//播放时长 = ( 文件大小 – ID3大小 ) × 8 ÷ 比特率(kbit/s)
	time=( Fsize - ID3size -ID3V1_size) * 8 / (_mp3FrameInfo.bitrate/1000);	
	return time;
}
#endif
					
	/*音频测试*/
void AUDIO_PLAY_Demo(void)
{
	char *path[]=
	{	
#ifdef WAV_EN			
		"0:/music/w1.wav",
		"0:/music/w2.wav",
		"0:/music/w3.wav",
		"0:/music/w4.wav",	
#endif	
#ifdef MP3_EN	
		"0:/music/m1.mp3",		
		"0:/music/m2.mp3",
		"0:/music/m3.mp3",
//		"0:/music/mp3_03.mp3",		
//		"0:/music/mp3_04.mp3",
//		"0:/music/mp3_05.mp3",
#endif		
		
		0
	};	
	int s=0;
	while(1)
	{
		/*播放*/
    MP3WAVplay(path[s]);
		/*下一曲*/
		s++;
		if(s>=((sizeof path)/(sizeof path[0])-1))s=0;
	}
}
/*****************************************************************************************/	
/*****************************************************************************************/	
/*设置hp电源*/
void AUDIO_play_power_hp(int power)	
{
	snd_soc_update_bits(codec, DAC_MIXER_CTRL,HP_POWER_EN,0x1,power);	/* power hp */
}
	
/*设置play音量 volume=0x00-0x3f
*/
void AUDIO_play_volume(int volume)	
{
	if(volume>0x3f)volume=0x3f;
	g_volume=volume;
  if((clock_init_f==1)&&(play_init_f==1))  
  {
		snd_soc_update_bits(codec, DAC_MIXER_CTRL,HP_VOL,0x3f,volume);/* set hp volume */	
	}
}

/*****************************************************************************************/	
/*****************************************************************************************/
#ifdef RECORED_EN
/*设置adc analog电源 1=使能 0=失能*/
void AUDIO_record_power_analog(int power)	
{
	snd_soc_update_bits(codec, 0X24,31,0x1,power);
}
/*设置录音通道 recored_ch=MICIN/FMINL/FMINR/LINEIN*/
void AUDIO_RECORD_CH_Init(int recored_ch)	
{
	snd_soc_update_bits(codec, 0X24,8,0x3F,(recored_ch&0x3f));//静音控制	
}
/*录音
FIL* fp ：文件指针
struct wav_ * wav_f ：wav信息
int recored_ch : 录音通道
*/
__align(4) u8 record_buff[48000*2*2];
int AUDIO_RECORD(char* path,struct wav_ * wav_f,int recored_ch)
{
//int dma_ch=1;//dma通道
int record_conut=0;//计时
int res=0;	
aFIL fp;
	
	/*音频初始化*/
	AUDIO_Init(0,1);
	AUDIO_RECORD_CH_Init(recored_ch);	
  AUDIO_RECORD_Init(wav_f);	
	AUDIO_DMA_Init();
	//
	res = AudioWriteFileHead(  &fp,//创建一个.WAV文件，并返回句柄
															path,		//	路径文件				
															wav_f->sample_rate*2*wav_f->play_time_s*wav_f->num_channels,//文件长度 = 采样率x2x时长
														  wav_f->sample_rate,//采样率
	                            wav_f->num_channels);//通道数
	if(res<0)
	{
		sysprintf("File err...\r\n");
		return -1;
	}
	//
	SET_AUDIO_DMA_DATA(2,(unsigned int *)record_buff,wav_f->sample_rate*2*wav_f->num_channels);
//	S_BIT(S_BIT(AUDIO_CODEC_CLK_REG,31);,31);
	//
	while(1)
	{	
		if(DMA_Get_Half_TIP(&record_dma))//半传输
		{
			  sysInvalidCache();//cache 
			  AudioWriteFileData(&fp,(PUINT16)((UINT32)(&record_buff[0])),wav_f->sample_rate*wav_f->num_channels);//存前半部分
		}			
		if(DMA_Get_Full_TIP(&record_dma))//全传输
		{
			record_conut++;	
			if(record_conut<wav_f->play_time_s)
			{
				DMA_Enable(&record_dma);//重启DMA
			}else
			{
//				C_BIT(AUDIO_CODEC_CLK_REG,31);//采集结束						
				DMA_Disable(&record_dma);	
			}
			sysInvalidCache();//cache 			
			AudioWriteFileData(&fp,(PUINT16)((UINT32)(&record_buff[wav_f->sample_rate*wav_f->num_channels])),wav_f->sample_rate*wav_f->num_channels);//存后半部分
			sysprintf("Time: %d S\r\n",record_conut);
			if(record_conut>=wav_f->play_time_s)
			{
				AudioWriteFileClose(&fp);//录制完成-关闭文件
				break;
			}
		}			
	}
	return 1;
}


/*音频录音测试*/
void AUDIO_RECORD_Demo(void)
{
struct    wav_ RECORD_WAV;
CHAR    	szFileName[128];	
INT32     i;

	sysprintf("AUDIO_RECORD_Demo...\r\n");
	//--------------------------------------
	RECORD_WAV.sample_rate=44100;//采样率 Supports ADC Sample Rates from 8KHz to 48KHz
	RECORD_WAV.bits_per_sample=16;//位宽16
	RECORD_WAV.num_channels=1;//通道
	RECORD_WAV.play_time_s=10;//时间秒
REBB://循环	
	for(i=0;i<1;i++)
	{	
		sysprintf("record Start...\r\n");
		//-----------------------------
		sprintf(szFileName, "0:/Au%d.WAV", i);//把 录音序号 打印到 字符串当中 形成路径文件
		sysprintf("path: %s\r\n",szFileName);
		AUDIO_RECORD(szFileName,&RECORD_WAV,MICIN);/*开始录音*/
		//------------------------------
		sysprintf("record end...\r\n\r\n");
	}

	for(i=0;i<1;i++)
	{
		sysprintf("play Start...\r\n");
		//-----------------------------
		sprintf(szFileName, "0:/Au%d.WAV", i);//把 录音序号 打印到 字符串当中 形成路径文件
		AUDIO_play_power_hp(1);
    AUDIO_record_power_analog(0);		
		MP3WAVplay(szFileName);
		AUDIO_play_power_hp(0);
    AUDIO_record_power_analog(1);			
		//------------------------------
		sysprintf("play end...\r\n\r\n");
	} 
 	
	goto REBB;
}
#endif


#ifdef AUDIO_ADC_EN
//----------------------------------------------------------------------
//----------------------------------------------------------------------
//----------------------------------------------------------------------
//----------------------------------------------------------------------
//----------------------------------------------------------------------
/*AUDIO单路读取ADC值，支持FMINL,FMINR,LINEIN
num=读多少次，最小为1，最大为32
返回值 位宽设置为16位时值为-32768到32768
*/
int AUDIO_read_adc_val(int num)
{
	if(num>32)num=32;//最大32
	if(num<0)num=1;//最小1
	while(1)
	{
		S_BIT(AUDIO_CODEC_CLK_REG,31);//开始采集
		int d=read32(AUDIO_BASE+0x14);		
		d=(d>>8)&0x3F;//8-12位为FIFO中数据的个数
		if(d>=num)
		{
			C_BIT(AUDIO_CODEC_CLK_REG,31);//结束采集
			int he=0;
			for(int i=0;i<num;i++)he+=read32(AUDIO_BASE+0x18);	//求和
			he/=num;//平均
			return he;//返回
		}
	}
}	
/*用音频ADC输入设置为普通ADC使用-支持FMINL,FMINR,LINEIN,
参数电压为模拟电压(3V)的一半1.5V，小于1.5输出负值，大于1.5输出正值,范围0-3V,
如果切换通道，切换后前面的测量值误差比较大，值变稳定时间也比较长，不建议切换方式检测多路电压,
*/
#include "stdlib.h"
void AUDIO_ADC_MODE_Demo(void)
{
struct    wav_ RECORD_WAV;
	sysprintf("AUDIO_ADC_MODE_Demo...\r\n");
	//--------------------------------------
	RECORD_WAV.sample_rate=8000;//采样率8K-范围8K-48K,设置为最低提高采样精度,需要按音频采样率设置
	RECORD_WAV.bits_per_sample=16;//位宽16-这里设置为16,范围值为-32768到32768
	RECORD_WAV.num_channels=1;//设置为1-只能一个通道
	//--------------------------------------
	AUDIO_Init(0,2);//ADC模式初始化
	AUDIO_RECORD_CH_Init(LINEIN);//设置输入通道	
  AUDIO_RECORD_Init(&RECORD_WAV);	
	//前面几个值误差较大，丢弃掉,可以多丢弃一些,
	AUDIO_read_adc_val(32);
	AUDIO_read_adc_val(32);
	while(1)
	{
		int adc_val=AUDIO_read_adc_val(32);//读取
		int V=(int)(((float)150/(float)32768)*(float)adc_val);
		int V1=abs(V);//正负电压
		int V2=V+152;//抬升1.5V转为正电压
		sysprintf("REG=%d V1=%s%d.%d%d V2=%s%d.%d%d\r\n",//串口输出显示
			adc_val,
			(V<0)?"-":"",V1/100,V1%100/10,V2%100%10,
			(V2<0)?"-":"",V2/100,V2%100/10,V2%100%10
		);
		delay_ms(300);
	}
}
#endif

#ifdef VIDEO_AVI_PLAY_WAV_EN
#include "avi.h"
/*****************************************************************************/
//DMA中断  视频播放时音频播放
/*****************************************************************************/
extern u8 saiplaybuf;
extern u8* saibuf[4];
extern u8* saibuf[4];
void DMA_ISR_Video(void)
{
saiplaybuf++;
if(saiplaybuf>3)saiplaybuf=0;	
	if(DMA_Get_Full_TIP(&play_dma))//全传输
	{
		SET_AUDIO_DMA_DATA(1,(unsigned int *)saibuf[saiplaybuf],avix.AudioBufSize);
	}	
}
// 视频播放时音频播放
int WAV_Video_Play_Init(int num_channels,int sample_rate)
{
static int wf=0;
	/*解WAV文件*/
	wav.audio_format=1;
	wav.num_channels=num_channels;		
	wav.bits_per_sample=16;
	wav.sample_rate=sample_rate;	
						
	/*输出*/
	sysprintf("采样格式:%d \r\n",wav.audio_format);
	sysprintf("采样通道:%d \r\n",wav.num_channels);
	sysprintf("采样位宽:%d bit\r\n",wav.bits_per_sample);
	sysprintf("采样周期:%d Hz\r\n",wav.sample_rate);
		
	/*无压缩格式*/
	if(wav.audio_format==1)
	{	
		if(wf==0)
		{
			/*音频初始化*/
			AUDIO_Init(1,0);
			AUDIO_DMA_Init();
			//开启中断				
			__IRQ_Init(IRQ_LEVEL_1,IRQ_DMA,DMA_ISR_Video,3,1);
			sysSetLocalInterrupt(ENABLE_IRQ);//开IRQ中断
      //
			wf=1;
		}			
		if(AUDIO_PLAY_Init(&wav)==0)
		{
			sysprintf("WAV_Play_Init OK \r\n");
		}
		sysprintf("buf size %d \r\n",avix.AudioBufSize);
		//dma初始化
		SET_AUDIO_DMA_DATA(1,(unsigned int *)saibuf[0],avix.AudioBufSize);
		DMA_Interrupt_Control_Full(&play_dma,dmaEnable);//使能中断
		//时钟选通
		S_BIT(AUDIO_CODEC_CLK_REG,31);
	}
	return 0;
}
// 视频播放的音频关闭
void WAV_Video_Play_close(void)
{
	//时钟关闭
	C_BIT(AUDIO_CODEC_CLK_REG,31);
	DMA_Interrupt_Control_Full(&play_dma,dmaDisable);//关中断
  DMA_Disable(&play_dma);
}
#endif

#ifdef NES_PLAY_WAV_EN
void NES_SET_AUDIO_DMA_DATA(int play_record,unsigned int *Source,unsigned int bcnt)
{
	if((play_record==1)||(play_record==3))//play
	{
		
		play_dma.Type=NDMA;//类型 
		play_dma.Ch=0;//通道 	
		play_dma.Byte_Counter=bcnt;//Byte计数	
		play_dma.Continuous_Mode_Enable=0;//连续模式
		play_dma.Read_Byte_Counter_Enable=0;//读计数值使能	
		//---------	
		play_dma.Source_Address=(unsigned int)(Source);//源地址	
		play_dma.Source_Address_Type=DMA_ADDRESS_TYEP_LINEER;//源地址类型
		play_dma.Source_DRQ_Type=NDMAS_DRQ_Type_SDRAM_Memory;//源类型
		play_dma.Source_Data_Width=DMA_DATA_WIDTH_16;//源数据宽度
		play_dma.Source_Burst_Length=DMA_BURST_LENGTH_1;//BURST
		//-----------	
		
		
		if(play_record==1)play_dma.Destination_Address=(unsigned int)(AUDIO_BASE+0x0C);//目标地址
#ifdef I2S_EN
			else if(play_record==3)play_dma.Destination_Address=(unsigned int)(I2S_BASE+SUNXI_DA_TXFIFO);//目标地址
#endif	
		play_dma.Destination_Address_Type=DMA_ADDRESS_TYEP_IO;//目标地址类型
		
		if(play_record==1)play_dma.Destination_DRQ_Type=NDMAD_DRQ_Type_Audio_Codec_DAC;//DAC
#ifdef I2S_EN
		else if(play_record==3)play_dma.Destination_DRQ_Type=NDMAD_DRQ_Type_Daudio;//IIS
#endif	
		play_dma.Destination_Data_Width=DMA_DATA_WIDTH_16;//目标数据宽度
		play_dma.Destination_Burst_Length=DMA_BURST_LENGTH_1;//BURST
		DMA_Config(&play_dma);
		DMA_Enable(&play_dma);	
		//-----------	
	}
}
int NES_WAV_Play_Init(void)
{
	/*解WAV文件*/
	wav.audio_format=1;
	wav.num_channels=1;		
	wav.bits_per_sample=16;
	wav.sample_rate=22050;	
						
	/*输出*/
	sysprintf("采样格式:%d \r\n",wav.audio_format);
	sysprintf("采样通道:%d \r\n",wav.num_channels);
	sysprintf("采样位宽:%d bit\r\n",wav.bits_per_sample);
	sysprintf("采样周期:%d Hz\r\n",wav.sample_rate);
			
	/*无压缩格式*/
	if(wav.audio_format==1)
	{	
		/*音频初始化*/
		AUDIO_Init(1,0);
		AUDIO_DMA_Init();
		if(AUDIO_PLAY_Init(&wav)==0)
		{
			//S_BIT(AUDIO_CODEC_CLK_REG,31);//时钟选通
			sysprintf("WAV_Play_Init OK \r\n");
		}
	}
	return 0;
}
//播放wav-
__align(4) unsigned short buff[2][0x400];
int Inxa=0,ns=0;
int au_f=0;
void NES_wav_play(unsigned char * wav_buff,int Size)
{
	unsigned short *bul;
	int i;
	bul=(unsigned short *)wav_buff;
 
	if(ns==0)
	{
		ns=1;
		NES_SET_AUDIO_DMA_DATA(1,(unsigned int *)buff[0],Size);
    S_BIT(AUDIO_CODEC_CLK_REG,31);//时钟选通		
		for(i=0;i<Size;i++)buff[0][i]=bul[i];	
	}else
	{
		if(Inxa==0)
		{
			Inxa=1;
			while(1)
			if(DMA_Get_Full_TIP(&play_dma))//全传输
			{
				NES_SET_AUDIO_DMA_DATA(1,(unsigned int *)buff[0],Size);
				for(i=0;i<Size;i++)buff[1][i]=bul[i];
				au_f++;
				break;
			}
		}else
		{
			Inxa=0;
			while(1)
			if(DMA_Get_Full_TIP(&play_dma))//全传输
			{							
				NES_SET_AUDIO_DMA_DATA(1,(unsigned int *)buff[1],Size);
				for(i=0;i<Size;i++)buff[0][i]=bul[i];
				au_f++;
				break;
			}
		}
	}
}
#endif
